/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package dale2507.gates.gate;

import dale2507.gates.GateDirectory;
import dale2507.gates.GatePlugin;
import dale2507.gates.gate.comparator.GateDHDComparator;
import dale2507.gates.gate.comparator.GateDisplayComparator;
import dale2507.gates.misc.DirectionSensitiveLocation;
import java.util.ArrayList;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockFromToEvent;
import org.bukkit.scheduler.BukkitScheduler;

/**
 *
 * @author Dale
 */
class Vortex implements Listener, Runnable {
    
    private DirectionSensitiveLocation dsl;
    private int vortexIncrement = 0;
    private ArrayList<Block> blocks = new ArrayList<Block>();
    private int taskId;
    private final BukkitScheduler scheduler;
    
    Vortex(DirectionSensitiveLocation dsl) {
        this.dsl = dsl;
        
        scheduler = Bukkit.getServer().getScheduler();
        taskId = scheduler.scheduleSyncRepeatingTask(GatePlugin.getInstance(), new Runnable() {
            @Override
            public void run() {
                vortexIncrement();
            }
        }, 5L, 5L);
        Bukkit.getServer().getPluginManager().registerEvents(this, GatePlugin.getInstance());
    }
    
    @EventHandler(priority = EventPriority.NORMAL)
    public void onBlockFromTo(BlockFromToEvent event) {
        if (blocks.contains(event.getBlock())) {
            event.setCancelled(true);
        }
    }
    
    private void vortexIncrement() {
        if (vortexIncrement < 4) {
            extendVortex();
        } else if (vortexIncrement >= 4 && vortexIncrement < 8) {
            collapseVortex();
        } else {
            this.forceFinish();
        }
        vortexIncrement++;
    }
    
    private void extendVortex() {
        int a=1;
        if (vortexIncrement > 2) a=2;
        
        for (int y=(0-a); y<=a; y++) {
            for (int x=(0-a); x<=a; x++) {
                if (!(Math.abs(x) == Math.abs(y) && Math.abs(x) == a)) {
                    Block b = dsl.getRelative(x, y, vortexIncrement).getBlock();
                    if (b.getType().equals(Material.SIGN_POST) ||
                            b.getType().equals(Material.SIGN) ||
                            b.getType().equals(Material.WALL_SIGN)) {
                        Gate g = GateDirectory.getInstance().getGate(new GateDisplayComparator(), b);
                        if (g != null) {
                            g.setStatus(Gate.Status.BROKEN);
                            GateDirectory.getInstance().deleteGate(g);
                        }
                    } else if (b.getType().equals(Material.CHEST)) {
                        // Set to broken and remove from directory if a gate chest is hit
                        Gate g = GateDirectory.getInstance().getGate(new GateDHDComparator(), b);
                        if (g != null) {
                            g.setStatus(Gate.Status.BROKEN);
                            GateDirectory.getInstance().deleteGate(g);
                        }
                    }

                    b.setTypeId(Material.STATIONARY_WATER.getId());
                    blocks.add(b);
                }
            }
        }
    }
    
    private void collapseVortex() {
        int a=1;
        if (vortexIncrement > 2 && vortexIncrement < 6) a=2;
        
        for (int y=(0-a); y<=a; y++) {
            for (int x=(0-a); x<=a; x++) {
                Block b = dsl.getRelative(x, y, 8-vortexIncrement).getBlock();
                if (blocks.contains(b)) {
                    b.setType(Material.AIR);
                    blocks.remove(b);
                }
            }
        }
        
        if (blocks.isEmpty()) GatePlugin.getInstance().getServer().getScheduler().cancelTask(taskId);
    }

    @Override
    public void run() {
        vortexIncrement();
    }
    
    public boolean isFinished() {
        return !(scheduler.isCurrentlyRunning(taskId) || scheduler.isQueued(taskId));
    }

    void forceFinish() {
        for (Block b : blocks) {
            b.setTypeId(0);
        }
        scheduler.cancelTask(taskId);
    }
    
}
